package com.cloud.easy.im.handler.strategy.websocket;

import com.cloud.easy.im.argeement.Agreement;
import com.cloud.easy.im.argeement.AgreementFactory;
import com.cloud.easy.im.argeement.AgreementType;
import com.cloud.easy.im.argeement.client.LoginInfo;
import com.cloud.easy.im.event.ServerEventListener;
import com.cloud.easy.im.handler.strategy.AgreementStrategy;
import com.cloud.easy.im.netty.IMObserver;
import com.cloud.easy.im.processor.OnlineProcessor;
import com.cloud.easy.im.utils.LocalSendHelper;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 客户端登陆请求处理器
 *
 * @author wangjian
 * @version 0.1.0
 * @create 2020年09月15日2:10 下午
 */
public class AgreementWebSocketCLoginHandler extends AgreementStrategy {

    private static final Logger logger = LoggerFactory.getLogger(AgreementWebSocketCLoginHandler.class);


    public AgreementWebSocketCLoginHandler() {
        super(AgreementType.C.FROM_CLIENT_TYPE_OF_LOGIN);
    }

    @Override
    public void handler(Channel session, Agreement dataFromClient, ServerEventListener serverEventListener) throws Exception {
        final LoginInfo loginInfo = AgreementFactory.parseLoginInfo(dataFromClient.getDataContent());
        logger.debug("[WS_LOGINE]>> loginInfo=" + loginInfo.toString());

        if (loginInfo.getLoginUserId() == null) {
            logger.warn("[WS_LOGINE]>> loginInfo或loginInfo.getLoginUserId()是null，无法登陆loginInfo=" + loginInfo + "]！");
            return;
        }
        if (serverEventListener == null) {
            logger.warn("[WS_LOGINE]>> 收到客户端登陆信息，但回调对象是null，没有进行回调.");
            return;
        }

        // 判断是否已经登陆(判断 channel 中有无用户 Id)
        boolean alreadyLogined = OnlineProcessor.isOnline(session);
        // 发送登陆成功后的回调观察者
        IMObserver imObserver = (sucess, extraObj) -> {
            if (sucess) {
                //在Attribute中存放用户id，以方便后续消息传递
                session.attr(OnlineProcessor.USER_ID_IN_SESSION_ATTRIBUTE_ATTR).set(loginInfo.getLoginUserId());
                session.attr(OnlineProcessor.PRODUCT_CODE_IN_SESSION_ATTRIBUTE_ATTR).set(dataFromClient.getProductCode());
                //存放进在线列表中
                OnlineProcessor.getInstance().putOnlineUser(loginInfo.getLoginUserId(), dataFromClient.getProductCode(), session);
                //登陆成功后回调
                serverEventListener
                        .onUserLoginAction_CallBack(loginInfo.getLoginUserId(), loginInfo.getExtra(), session);
            } else {
                logger.warn("[WS_LOGINE]>> 发给客户端[userid:" + loginInfo.getLoginUserId() + ",productCode:" + dataFromClient.getProductCode() + "]的登陆成功信息发送失败了！");
            }
        };

        if (alreadyLogined) {
            //如果已经登陆
            logger.debug("[WS_LOGINE]>> 客户端[userid:" + loginInfo.getLoginUserId() + ",productCode:" + dataFromClient.getProductCode() + "]已经登陆过，但还在尝试重新登陆");

            LocalSendHelper.sendData(session,
                    AgreementFactory.createLoginInfoResponse((byte) 0, loginInfo.getLoginUserId(), dataFromClient.getProductCode()),
                    imObserver);
            return;
        }

        // 首次登陆
        // 回调登陆校验
        byte code = serverEventListener.onVerifyUser_CallBack(
                loginInfo.getLoginUserId(), loginInfo.getLoginToken(), loginInfo.getExtra(), session);
        if (code != 0) {
            // 登陆失败，返回失败结果
            logger.debug("[WS_LOGINE]>> 客户端[userid:" + loginInfo.getLoginUserId() + ",productCode:" + dataFromClient.getProductCode() + "]回调登陆校验接口，接口返回结果失败！code：" + code);
            LocalSendHelper.sendData(session,
                    AgreementFactory.createLoginInfoResponse(code, loginInfo.getLoginUserId(), dataFromClient.getProductCode()),
                    null);
            return;
        }
        // 登陆成功
        LocalSendHelper.sendData(session,
                AgreementFactory.createLoginInfoResponse(code, loginInfo.getLoginUserId(), dataFromClient.getProductCode()),
                imObserver);
    }
}
